#include "Symbol.h"
#include <string.h>
namespace SymCe{
	bool Symbol::operator==(const Symbol & symbol) const{
		if (type!=symbol.type){
			return false;
		}
		switch(type){
			case FUNCTION:
				return func == symbol.func;
				break;
			case NUMBER:
				return number == symbol.number;
				break;
			case OPERATOR:
				return oper == symbol.oper;
				break;
			case VARIABLE:
				return (strcmp(name, symbol.name) == 0);
				break;
			case CONSTANT:
				return ((strcmp(name, symbol.name) == 0) && (number == symbol.number));
				break;
			default:
				return false;
		}
	}

	bool Symbol::operator<(const Symbol & symbol)const{
		//Numbers first :-)
		//And this should be deterministic!
		if(type != symbol.type){
			return type < symbol.type;
		}

		switch (type){
			case NUMBER:
				return number<symbol.number;
				break;
			case FUNCTION:
				return func < symbol.func;
				break;
			case OPERATOR:
				return oper < symbol.oper;
				break;
			case VARIABLE:
				if(strcmp(name, symbol.name)<0){
					return true;
				}else{
					return false;
				}
				break;
			case CONSTANT:
				int tmp = strcmp(name, symbol.name);
				if(tmp < 0){
					return true;
				}
				if(tmp == 0){
					return number < symbol.number;
				}
				return false;
				break;
		}
		//We should not get here.
		return false;
	}

	Symbol & Symbol::operator=(const Symbol & symbol){
		if(this!=&symbol){
			type=symbol.type;
			//Just copy them all. However, copy name only when needed.
			func=symbol.func;
			oper=symbol.oper;
			number=symbol.number;
			if(type == VARIABLE || type==CONSTANT){ //copy name, if needed.
				size_t length = strlen(symbol.name);
				delete name;
				name=new char[length+1];
				strcpy(name, symbol.name);
			}
		}
		//and return it.
		return *this;
	}

	Symbol::Symbol(){
		//symbol is generated in every multitree and filled from there.
		//however, in most of the cases we need name to be empty. Let's set it to NULL.
		name=NULL;
	}

	Symbol::Symbol(const Symbol & symbol){
		type=symbol.type;
		//Just copy them all. However, copy name only when needed.
		func=symbol.func;
		oper=symbol.oper;
		number=number;
		if(type == VARIABLE || type==CONSTANT){ //copy name, if needed.
			size_t length = strlen(symbol.name);
			name=new char[length+1];
			strcpy(name, symbol.name);
		}
	}


	Symbol::~Symbol(){
		delete name;
		name=NULL;
	}




}

